package org.yookiee.support.core;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.IOException;
import java.util.Date;

/**
 * FileName CustomObjectMapper
 * Package org.jeecg.config.i18n.config
 * Description
 * author cpstory
 * create 2023-11-29 13:39
 * version V1.0
 */
public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Date.class, new CustomDateDeserializer());
        module.addSerializer(Date.class, new CustomDateSerializer());
        this.registerModule(module);
    }

    private static class CustomDateDeserializer extends StdDeserializer<Date> implements ContextualDeserializer {

        private String pattern;

        public CustomDateDeserializer() {
            super(Date.class);
        }

        private CustomDateDeserializer(String pattern) {
            super(Date.class);
            this.pattern = pattern;
        }

        @Override
        public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
            DateTimeFormat dateTimeFormat = property.getAnnotation(DateTimeFormat.class);
            String pattern = (dateTimeFormat != null) ? dateTimeFormat.pattern() : null;
            return new CustomDateDeserializer(pattern);
        }

        @Override
        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            TimeZoneDateFormat dateFormat = new TimeZoneDateFormat(pattern);
            return dateFormat.parse(p.getValueAsString());
        }
    }

    private static class CustomDateSerializer extends StdSerializer<Date> implements ContextualSerializer {

        private String pattern;

        public CustomDateSerializer() {
            this(null);
        }

        private CustomDateSerializer(String pattern) {
            super(Date.class);
            this.pattern = pattern;
        }

        @Override
        public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            TimeZoneDateFormat dateFormat = new TimeZoneDateFormat(pattern);
            gen.writeString(dateFormat.format(value));
        }

        @Override
        public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
            DateTimeFormat dateTimeFormat = property.getAnnotation(DateTimeFormat.class);
            String pattern = (dateTimeFormat != null) ? dateTimeFormat.pattern() : "yyyy-MM-dd HH:mm:ss";
            return new CustomDateSerializer(pattern);
        }
    }

}
